/***************************************************************************
 *   Copyright (C) 2008 by BogDan Vatra                                    *
 *   taipan@licentia.eu                                                    *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include <QPainter>
#include <QPalette>
#include <QFontMetrics>
#include <QMouseEvent>

#include "operatiunicontabilewidget.h"

OperatiuniContabileWidget::OperatiuniContabileWidget(QWidget *parent)
		: KontAMabilWindow(parent)
{
	m_rows=5;
	m_rowIndentation=6;
	m_columnIndentation=6;
	m_border=5;
	m_mousePos=QPoint(0,0);
	setMouseTracking(true);
	m_mouseOverCell.col=-1;
	m_mouseOverCell.row=-1;
	m_oldMouseOverCell=m_mouseOverCell;
	m_currentCell.col=0;
	m_currentCell.row=0;
	setFocusPolicy(Qt::StrongFocus);
	setMinimumWidth(602);
	setMaximumWidth(602);
}


OperatiuniContabileWidget::~OperatiuniContabileWidget()
{
}

QRect OperatiuniContabileWidget::cellRect(Cell cell)
{
	return cellRect(cell.col, cell.row);
}

QRect OperatiuniContabileWidget::cellRect(int col, int row)
{
	QRect rect;

	if (col<0 || row<0 || row>m_rows)
		return rect;

	int rowHeight=fontMetrics().height()+m_rowIndentation;

	QFont fontt=font();
	fontt.setBold(true);

	int topHeader=4+QFontMetrics(fontt).height();
	int w=width()-m_border*2;

	rect.setY(topHeader+m_border+row*rowHeight);
	rect.setHeight(rowHeight);

	rect.setX(m_border+col*w/4);
	rect.setWidth(col<2?w/4:w/2);
	return rect;
}

OperatiuniContabileWidget::Cell OperatiuniContabileWidget::cellAt(const QPoint & point)
{
	Cell c;
	c.row=-1;
	c.col=-1;
	int rowHeight=fontMetrics().height()+m_rowIndentation;

	QFont fontt=font();
	fontt.setBold(true);

	int topHeader=4+QFontMetrics(fontt).height();
	int w=width()-m_border*2;
	int h=rowHeight*m_rows;

	QRect cellsRect(m_border, topHeader+m_border, w, h);
	if (!cellsRect.contains(point))
		return c;
	int x=point.x()-m_border;
	int y=point.y()-m_border-topHeader;

	c.col=(x<w/4)?0:(x<w/2)?1:2;
	c.row=y/rowHeight;
	return c;
}

OperatiuniContabileWidget::Cell OperatiuniContabileWidget::currentCell()
{
	return m_currentCell;
}

void OperatiuniContabileWidget::currentCell(int * col, int * row)
{
	if (col && row)
	{
		*col=m_currentCell.col;
		*row=m_currentCell.row;
	}
}

void OperatiuniContabileWidget::setCurrentCell(Cell cell)
{
	OperatiuniContabileWidget::setCurrentCell(cell.col, cell.row);
}

void OperatiuniContabileWidget::setCurrentCell(int col, int row)
{
	if ((m_currentCell.col==col && m_currentCell.row==row) || col<0 || col>2 || row<0 || row>m_rows)
		return;

	Cell c=m_currentCell;
	m_currentCell.col=col;
	m_currentCell.row=row;
	update(cellRect(c));
	update(cellRect(m_currentCell));
	emit(currentChanged(col, row));
}

void OperatiuniContabileWidget::mousePressEvent(QMouseEvent * event)
{
	if (event->button()==Qt::LeftButton)
		setCurrentCell(cellAt(event->pos()));
}

void OperatiuniContabileWidget::mouseDoubleClickEvent(QMouseEvent * event)
{
	if (event->button()==Qt::LeftButton)
	{
		Cell c=cellAt(event->pos());
		emit(editCell(c.col, c.row, cellRect(c),QString()));
	}
}

void OperatiuniContabileWidget::mouseMoveEvent(QMouseEvent * event)
{
	m_mousePos=event->pos();
	m_oldMouseOverCell=m_mouseOverCell;
	m_mouseOverCell=cellAt(m_mousePos);
	QWidget::mouseMoveEvent(event);
	if (m_mouseOverCell.col!=m_oldMouseOverCell.col || m_mouseOverCell.row!=m_oldMouseOverCell.row)
	{
		update(cellRect(m_oldMouseOverCell));
		update(cellRect(m_mouseOverCell));
	}
}

void OperatiuniContabileWidget::prepareCell(int col, int row, const QRect & rect, QPainter & painter)
{
	QPalette p;
	painter.fillRect(rect,(m_currentCell.col==col  && m_currentCell.row == row)?p.highlight():(m_mouseOverCell.col==col && m_mouseOverCell.row==row)?p.midlight():p.base());
	if (m_currentCell.col==col  && m_currentCell.row == row)
	{
		painter.setBrush(p.highlightedText());
		QPen pen=painter.pen();
		pen.setBrush(p.highlightedText());
		painter.setPen(pen);
		painter.setBackground(p.highlight());
	}
}

int OperatiuniContabileWidget::rows()
{
	return m_rows;
}
void OperatiuniContabileWidget::setRows(int nrows)
{
	m_rows=nrows;
}

void OperatiuniContabileWidget::keyPressEvent( QKeyEvent * event )
{
	switch(event->key())
	{
		case Qt::Key_0:
		case Qt::Key_1:
		case Qt::Key_2:
		case Qt::Key_3:
		case Qt::Key_4:
		case Qt::Key_5:
		case Qt::Key_6:
		case Qt::Key_7:
		case Qt::Key_8:
		case Qt::Key_9:
		case Qt::Key_Minus:
		case Qt::Key_Slash:
			emit(editCell(m_currentCell.col, m_currentCell.row, cellRect(m_currentCell),event->text()));
			break;

		case Qt::Key_Delete:
			if (event->modifiers()!=Qt::NoModifier)
				break;
			if (m_currentCell.col!=-1 && m_currentCell.row!=-1)
				emit(deletePressed(m_currentCell.col, m_currentCell.row));
			break;


		case Qt::Key_PageUp:
			if (!m_rows)
				break;
			if (event->modifiers()&Qt::ControlModifier)
			{
				setCurrentCell(m_currentCell.col,0);
				break;
			}
			break;

		case Qt::Key_PageDown:
			if (!m_rows)
				break;
			if (event->modifiers()&Qt::ControlModifier)
			{
				setCurrentCell(m_currentCell.col,m_rows-1);
				break;
			}
			break;

		case Qt::Key_Home:
			if (!m_rows)
				break;
			if (event->modifiers()&Qt::ControlModifier)
			{
				setCurrentCell(m_currentCell.col,0);
				break;
			}

			if (!m_currentCell.col)
				setCurrentCell(0,0);
			else
				setCurrentCell(0,m_currentCell.row);
			break;

		case Qt::Key_End:
			if (!m_rows)
				break;

			if (event->modifiers()&Qt::ControlModifier)
			{
				setCurrentCell(m_currentCell.col,m_rows-1);
				break;
			}
			if (2==m_currentCell.col)
				setCurrentCell(2,m_rows-1);
			else
				setCurrentCell(2,m_currentCell.row);
			break;

		case Qt::Key_Right:
			if (!m_rows)
				break;
			if (m_currentCell.col<2)
				setCurrentCell(m_currentCell.col+1,m_currentCell.row);
/*
			else
				if (m_currentCell.row<m_rows-1)
					setCurrentCell(0,m_currentCell.row+1);
*/
			break;

		case Qt::Key_Left:
			if (!m_rows)
				break;
			if (m_currentCell.col)
				setCurrentCell(m_currentCell.col-1,m_currentCell.row);
/*
			else
				if (m_currentCell.row)
					setCurrentCell(2,m_currentCell.row-1);
*/
			break;

		case Qt::Key_Up:
			if (!m_rows)
				break;
			if (m_currentCell.row)
				setCurrentCell(m_currentCell.col,m_currentCell.row-1);
			break;

		case Qt::Key_Down:
			if (!m_rows)
				break;
			if (m_currentCell.row<m_rows-1)
				setCurrentCell(m_currentCell.col,m_currentCell.row+1);
			break;
		case Qt::Key_Escape:
			close();
			break;
	}
	QWidget::keyPressEvent( event );
}

void OperatiuniContabileWidget::paintEvent(QPaintEvent *event)
{
	QPainter painter(this);
	QPalette p;

	painter.translate(m_border,m_border);


	int w=width()-m_border*2;
	int h=height()-m_border*2;

	int rowHeight=painter.fontMetrics().height()+m_rowIndentation;

	painter.save();
	QFont font=painter.font();
	font.setBold(true);
	painter.setFont(font);

	int topHeader=4+painter.fontMetrics().height();

	if (event->rect().translated(-painter.transform().dx(),-painter.transform().dy()).contains(QRect(0, 0, w, topHeader-2)))
	{
		painter.fillRect(0, 0, w, topHeader-2, p.highlight());
		painter.drawRect(0, 0, w, topHeader-2);
		painter.drawLine(w/4, 0, w/4, topHeader-2);
		painter.drawLine(w/2, 0, w/2, topHeader-2);

		painter.drawText(0, 2, w/4, topHeader-4,  Qt::AlignCenter, tr("Cont debitor"));
		painter.drawText(w/4, 2, w/4, topHeader-4,  Qt::AlignCenter, tr("Cont creditor"));
		painter.drawText(w/2, 2,w/2, topHeader-4,  Qt::AlignCenter, tr("Suma"));
	}
	painter.restore();

	if (event->rect().translated(-painter.transform().dx(),-painter.transform().dy()).contains(QRect(0, topHeader, w, h-topHeader)))
		painter.fillRect(0, topHeader, w, h-topHeader, p.base());

	if (event->rect().translated(-painter.transform().dx(),-painter.transform().dy()).intersects(QRect(0, topHeader, w, h-topHeader)))
		painter.drawRect(0, topHeader, w, h-topHeader);

	painter.translate(0, topHeader);

	for (int i=0;i<m_rows;i++)
	{
		if (event->rect().translated(-painter.transform().dx(),-painter.transform().dy()).contains(QRect(1, i*rowHeight+1, w/4-1, rowHeight-1)))
		{
			painter.save();
			prepareCell(0,i,QRect(1, i*rowHeight+1, w/4-1, rowHeight-1),painter);
			emit(paintCell(0,i, painter, QRect(m_columnIndentation/2, i*rowHeight+1, w/4-m_columnIndentation, rowHeight-1),0));
			painter.restore();
		}

		if (event->rect().translated(-painter.transform().dx(),-painter.transform().dy()).contains(QRect(w/4+1, i*rowHeight+1, w/4-1, rowHeight-1)))
		{
			painter.save();
			prepareCell(1,i,QRect(w/4+1, i*rowHeight+1, w/4-1, rowHeight-1),painter);
			emit(paintCell(1, i, painter, QRect(w/4+m_columnIndentation/2, i*rowHeight+1, w/4-m_columnIndentation, rowHeight-1),0));
			painter.restore();
		}

		if (event->rect().translated(-painter.transform().dx(),-painter.transform().dy()).contains(QRect(w/2+1, i*rowHeight+1, w/2-1, rowHeight-1)))
		{
			painter.save();
			prepareCell(2,i,QRect(w/2+1, i*rowHeight+1, w/2-1, rowHeight-1),painter);
			emit(paintCell(2, i, painter, QRect(w/2+m_columnIndentation/2, i*rowHeight+1, w/2-m_columnIndentation, rowHeight-1),0));
			painter.restore();
		}
		painter.drawLine(0, i*rowHeight+rowHeight, w, i*rowHeight+rowHeight);
	}
	painter.drawLine(w/4, 0, w/4, m_rows*rowHeight);
	painter.drawLine(w/2, 0, w/2, m_rows*rowHeight);
	event->setAccepted(true);
}

